package chrisbode.cps142.a1;

import java.text.NumberFormat;

public class TimeOfDay {
	private int hours, minutes, seconds;

	/**
	 * Creates an instance of TimeOfDay that represents midnight. (00:00:00)
	 */
	public TimeOfDay() {
		this.hours = 0;
		this.minutes = 0;
		this.seconds = 0;
	}

	/**
	 * @param hours
	 * @param minutes
	 * @param seconds
	 */
	public TimeOfDay(int hours, int minutes, int seconds) {
		this.hours = hours;
		this.minutes = minutes;
		this.seconds = seconds;
	}

	/**
	 * Copy constructor
	 * 
	 * @param toCopy
	 *            The instance to copy.
	 */
	public TimeOfDay(TimeOfDay toCopy) {
		this.hours = toCopy.hours;
		this.minutes = toCopy.minutes;
		this.seconds = toCopy.seconds;
	}

	public void setTime(int hours, int minutes, int seconds) {
		this.setHours(hours);
		this.setMinutes(minutes);
		this.setSeconds(seconds);
	}

	/**
	 * @return the hours
	 */
	public int getHours() {
		return hours;
	}

	/**
	 * @param hours
	 *            the hours to set
	 */
	public void setHours(int hours) {
		if (hours < 24 && hours >= 0) {
			this.hours = hours;
		} else {
			this.hours = 0;
		}
	}

	/**
	 * @return the minutes
	 */
	public int getMinutes() {
		return minutes;
	}

	/**
	 * @param minutes
	 *            the minutes to set
	 */
	public void setMinutes(int minutes) {
		if (minutes < 60 && minutes >= 0) {
			this.minutes = minutes;
		} else {
			this.minutes = 0;
		}
	}

	/**
	 * @return the seconds
	 */
	public int getSeconds() {
		return seconds;
	}

	/**
	 * @param seconds
	 *            the seconds to set
	 */
	public void setSeconds(int seconds) {
		if (seconds < 60 && seconds >= 0) {
			this.seconds = seconds;
		} else {
			this.seconds = 0;
		}
	}

	public void incrementOneSecond() {
		this.seconds++;
		if (this.seconds >= 60) {
			this.seconds = 0;
			this.incrementOneMinute();
		}
	}

	public void incrementOneMinute() {
		this.minutes++;
		if (this.minutes >= 60) {
			this.minutes = 0;
			this.incrementOneHour();
		}
	}

	public void incrementOneHour() {
		this.hours++;
		if (this.hours >= 24) {
			this.hours = 0;
		}
	}

	private static final NumberFormat twoDigit = NumberFormat.getInstance();

	static {
		twoDigit.setMaximumIntegerDigits(2);
		twoDigit.setMinimumIntegerDigits(2);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return twoDigit.format(hours) + ":" + twoDigit.format(minutes) + ":"
				+ twoDigit.format(seconds);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + hours;
		result = prime * result + minutes;
		result = prime * result + seconds;
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof TimeOfDay))
			return false;
		TimeOfDay other = (TimeOfDay) obj;
		if (hours != other.hours)
			return false;
		if (minutes != other.minutes)
			return false;
		if (seconds != other.seconds)
			return false;
		return true;
	}

	/**
	 * @return Deep copy of this instance.
	 */
	public TimeOfDay copy() {
		return new TimeOfDay(this);
	}

	/**
	 * Creates a TimeOfDay from a String formatted as HH:MM:SS. Returns null if
	 * the string can't be converted.
	 * 
	 * @param time
	 * @return A TimeOfDay instance representing the supplied time.
	 */
	public static TimeOfDay createFromString(String time) {
		String[] parts = time.split("\\:", 3);

		if (parts.length != 3)
			return null;

		try {
			int hours, minutes, seconds;
			hours = Integer.parseInt(parts[0]);
			minutes = Integer.parseInt(parts[1]);
			seconds = Integer.parseInt(parts[2]);
			
			return new TimeOfDay(hours, minutes, seconds);
		} catch (NumberFormatException e) {
			return null;
		}
	}
}
